12 #if defined(US_AUTH_PEERCRED_UCRED) || defined(US_AUTH_PEERCRED_SOCKPEERCRED)
13 # ifdef US_AUTH_PEERCRED_UCRED
18 # include <sys/socket.h>
19 #elif defined(US_AUTH_GETPEERUCRED)
23 #include <sys/param.h>
26 #include <sys/types.h>
42 #define PCMK_IPC_VERSION 1
45 #define PCMK_IPC_DEFAULT_QUEUE_MAX 500
47 struct crm_ipc_response_header {
48 struct qb_ipc_response_header qb;
49 uint32_t size_uncompressed;
50 uint32_t size_compressed;
55 static int hdr_offset = 0;
56 static unsigned int ipc_buffer_max = 0;
57 static unsigned int pick_ipc_buffer(
unsigned int max);
62 if (hdr_offset == 0) {
63 hdr_offset =
sizeof(
struct crm_ipc_response_header);
65 if (ipc_buffer_max == 0) {
66 ipc_buffer_max = pick_ipc_buffer(0);
73 return pick_ipc_buffer(0);
77 generateReference(
const char *custom1,
const char *custom2)
79 static uint ref_counter = 0;
82 (custom1? custom1 :
"_empty_"),
83 (custom2? custom2 :
"_empty_"),
84 (
long long) time(NULL), ref_counter++);
89 const char *host_to,
const char *sys_to,
90 const char *sys_from,
const char *uuid_from,
const char *origin)
92 char *true_from = NULL;
93 xmlNode *request = NULL;
94 char *reference = generateReference(task, sys_from);
96 if (uuid_from != NULL) {
98 }
else if (sys_from != NULL) {
99 true_from = strdup(sys_from);
101 crm_err(
"No sys from specified");
116 if (host_to != NULL && strlen(host_to) > 0) {
120 if (msg_data != NULL) {
133 create_reply_adv(xmlNode * original_request, xmlNode * xml_response_data,
const char *origin)
135 xmlNode *reply = NULL;
145 crm_err(
"Cannot create new_message, no message type in original message");
150 crm_err(
"Cannot create new_message, original message was not a request");
156 crm_err(
"Cannot create new_message, malloc failed");
172 if (host_from != NULL && strlen(host_from) > 0) {
176 if (xml_response_data != NULL) {
187 static GHashTable *client_connections = NULL;
198 return client_connections? g_hash_table_size(client_connections) : 0;
213 if ((func != NULL) && (client_connections != NULL)) {
214 g_hash_table_foreach(client_connections, func, user_data);
230 if ((func != NULL) && (client_connections != NULL)) {
231 g_hash_table_foreach_remove(client_connections, func, user_data);
238 if (client_connections) {
239 return g_hash_table_lookup(client_connections, c);
253 if (client_connections &&
id) {
254 g_hash_table_iter_init(&iter, client_connections);
255 while (g_hash_table_iter_next(&iter, &key, (gpointer *) & client)) {
256 if (strcmp(client->id,
id) == 0) {
262 crm_trace(
"No client found with id=%s",
id);
271 }
else if (c->
name == NULL && c->
id == NULL) {
273 }
else if (c->
name == NULL) {
283 switch (client_type) {
288 #ifdef HAVE_GNUTLS_GNUTLS_H
289 case PCMK__CLIENT_TLS:
300 if (client_connections != NULL) {
301 int active = g_hash_table_size(client_connections);
304 crm_err(
"Exiting with %d active IPC client%s",
307 g_hash_table_destroy(client_connections); client_connections = NULL;
314 qb_ipcs_connection_t *c = NULL;
316 if (service == NULL) {
320 c = qb_ipcs_connection_first_get(service);
323 qb_ipcs_connection_t *last = c;
325 c = qb_ipcs_connection_next_get(service, last);
328 crm_notice(
"Disconnecting client %p, pid=%d...",
330 qb_ipcs_disconnect(last);
331 qb_ipcs_connection_unref(last);
346 client_from_connection(qb_ipcs_connection_t *c,
void *key, uid_t uid_client)
350 if (client == NULL) {
358 if (client->
user == NULL) {
359 client->
user = strdup(
"#unprivileged");
361 crm_err(
"Unable to enforce ACLs for user ID %d, assuming unprivileged",
374 if (client->
id == NULL) {
375 crm_err(
"Could not generate UUID for client");
383 if (client_connections == NULL) {
385 client_connections = g_hash_table_new(g_direct_hash, g_direct_equal);
387 g_hash_table_insert(client_connections, key, client);
410 gid_t uid_cluster = 0;
411 gid_t gid_cluster = 0;
418 static bool need_log = TRUE;
421 crm_warn(
"Could not find user and group IDs for user %s",
427 if (uid_client != 0) {
428 crm_trace(
"Giving group %u access to new IPC connection", gid_cluster);
430 qb_ipcs_connection_auth_set(c, -1, gid_cluster, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
434 client = client_from_connection(c, NULL, uid_client);
435 if (client == NULL) {
439 if ((uid_client == 0) || (uid_client == uid_cluster)) {
444 crm_debug(
"New IPC client %s for PID %u with uid %d and gid %d",
445 client->
id, client->
pid, uid_client, gid_client);
449 static struct iovec *
450 pcmk__new_ipc_event(
void)
452 struct iovec *iov = calloc(2,
sizeof(
struct iovec));
467 free(event[0].iov_base);
468 free(event[1].iov_base);
474 free_event(gpointer
data)
495 if (client_connections) {
497 crm_trace(
"Destroying %p/%p (%d remaining)",
498 c, c->
ipcs, g_hash_table_size(client_connections) - 1);
499 g_hash_table_remove(client_connections, c->
ipcs);
502 crm_trace(
"Destroying remote connection %p (%d remaining)",
503 c, g_hash_table_size(client_connections) - 1);
504 g_hash_table_remove(client_connections, c->
id);
547 if ((errno == 0) && (qmax_int > 0)) {
548 client->
queue_max = (
unsigned int) qmax_int;
558 struct qb_ipcs_connection_stats stats;
560 stats.client_pid = 0;
561 qb_ipcs_connection_stats_get(c, &stats, 0);
562 return stats.client_pid;
581 char *uncompressed = NULL;
582 char *text = ((
char *)
data) +
sizeof(
struct crm_ipc_response_header);
583 struct crm_ipc_response_header *header =
data;
586 *
id = ((
struct qb_ipc_response_header *)
data)->id;
589 *
flags = header->flags;
601 crm_err(
"Filtering incompatible v%d IPC message, we only support versions <= %d",
606 if (header->size_compressed) {
608 unsigned int size_u = 1 + header->size_uncompressed;
609 uncompressed = calloc(1, size_u);
611 crm_trace(
"Decompressing message data %u bytes into %u bytes",
612 header->size_compressed, size_u);
614 rc = BZ2_bzBuffToBuffDecompress(uncompressed, &size_u, text, header->size_compressed, 1, 0);
625 CRM_ASSERT(text[header->size_uncompressed - 1] == 0);
637 crm_ipcs_flush_events_cb(gpointer
data)
642 crm_ipcs_flush_events(c);
657 guint
delay = (queue_len < 5)? (1000 + 100 * queue_len) : 1500;
675 unsigned int sent = 0;
676 unsigned int queue_len = 0;
691 struct crm_ipc_response_header *header = NULL;
692 struct iovec *
event = NULL;
702 qb_rc = qb_ipcs_event_sendv(c->
ipcs, event, 2);
710 header =
event[0].iov_base;
711 if (header->size_compressed) {
712 crm_trace(
"Event %d to %p[%d] (%lld compressed bytes) sent",
713 header->qb.id, c->
ipcs, c->
pid, (
long long) qb_rc);
715 crm_trace(
"Event %d to %p[%d] (%lld bytes) sent: %.120s",
716 header->qb.id, c->
ipcs, c->
pid, (
long long) qb_rc,
717 (
char *) (event[1].iov_base));
723 if (sent > 0 || queue_len) {
724 crm_trace(
"Sent %d events (%d remaining) for %p[%d]: %s (%lld)",
725 sent, queue_len, c->
ipcs, c->
pid,
736 if ((c->
queue_backlog <= 1) || (queue_len < c->queue_backlog)) {
738 crm_warn(
"Client with process ID %u has a backlog of %u messages "
741 crm_err(
"Evicting client with process ID %u due to backlog of %u messages "
744 qb_ipcs_disconnect(c->
ipcs);
750 delay_next_flush(c, queue_len);
774 uint32_t max_send_size,
struct iovec **result,
777 static unsigned int biggest = 0;
779 unsigned int total = 0;
780 char *compressed = NULL;
782 struct crm_ipc_response_header *header = NULL;
784 if ((message == NULL) || (result == NULL)) {
788 header = calloc(1,
sizeof(
struct crm_ipc_response_header));
789 if (header == NULL) {
796 if (max_send_size == 0) {
797 max_send_size = ipc_buffer_max;
802 iov = pcmk__new_ipc_event();
803 iov[0].iov_len = hdr_offset;
804 iov[0].iov_base = header;
807 header->size_uncompressed = 1 + strlen(buffer);
808 total = iov[0].iov_len + header->size_uncompressed;
810 if (total < max_send_size) {
811 iov[1].iov_base = buffer;
812 iov[1].iov_len = header->size_uncompressed;
815 unsigned int new_size = 0;
817 if (
pcmk__compress(buffer, (
unsigned int) header->size_uncompressed,
818 (
unsigned int) max_send_size, &compressed,
822 header->size_compressed = new_size;
824 iov[1].iov_len = header->size_compressed;
825 iov[1].iov_base = compressed;
829 biggest = QB_MAX(header->size_compressed, biggest);
833 biggest = QB_MAX(header->size_uncompressed, biggest);
835 crm_err(
"Could not compress %u-byte message into less than IPC "
836 "limit of %u bytes; set PCMK_ipc_buffer to higher value "
837 "(%u bytes suggested)",
838 header->size_uncompressed, max_send_size, 4 * biggest);
847 header->qb.size = iov[0].iov_len + iov[1].iov_len;
848 header->qb.id = (int32_t)request;
853 *bytes = header->qb.size;
862 static uint32_t
id = 1;
863 struct crm_ipc_response_header *header = iov[0].iov_base;
875 header->flags |=
flags;
877 header->qb.id =
id++;
884 struct iovec *iov_copy = pcmk__new_ipc_event();
887 iov_copy[0].iov_len = iov[0].iov_len;
888 iov_copy[0].iov_base = malloc(iov[0].iov_len);
889 memcpy(iov_copy[0].iov_base, iov[0].iov_base, iov[0].iov_len);
891 iov_copy[1].iov_len = iov[1].iov_len;
892 iov_copy[1].iov_base = malloc(iov[1].iov_len);
893 memcpy(iov_copy[1].iov_base, iov[1].iov_base, iov[1].iov_len);
895 add_event(c, iov_copy);
903 qb_rc = qb_ipcs_response_sendv(c->
ipcs, iov, 2);
904 if (qb_rc < header->qb.size) {
908 crm_notice(
"Response %d to pid %d failed: %s "
909 CRM_XS " bytes=%u rc=%lld ipcs=%p",
911 header->qb.size, (
long long) qb_rc, c->
ipcs);
914 crm_trace(
"Response %d sent, %lld bytes to %p[%d]",
915 header->qb.id, (
long long) qb_rc, c->
ipcs, c->
pid);
924 rc = crm_ipcs_flush_events(c);
926 crm_ipcs_flush_events(c);
929 if ((
rc == EPIPE) || (
rc == ENOTCONN)) {
939 struct iovec *iov = NULL;
959 uint32_t request, uint32_t
flags,
const char *tag)
986 qb_ipcs_service_t **ipcs_rw,
987 qb_ipcs_service_t **ipcs_shm,
988 struct qb_ipcs_service_handlers *ro_cb,
989 struct qb_ipcs_service_handlers *rw_cb)
992 QB_IPC_NATIVE, ro_cb);
995 QB_IPC_NATIVE, rw_cb);
1000 if (*ipcs_ro == NULL || *ipcs_rw == NULL || *ipcs_shm == NULL) {
1001 crm_err(
"Failed to create the CIB manager: exiting and inhibiting respawn");
1002 crm_warn(
"Verify pacemaker and pacemaker_remote are not both enabled");
1020 qb_ipcs_service_t *ipcs_rw,
1021 qb_ipcs_service_t *ipcs_shm)
1023 qb_ipcs_destroy(ipcs_ro);
1024 qb_ipcs_destroy(ipcs_rw);
1025 qb_ipcs_destroy(ipcs_shm);
1052 struct qb_ipcs_service_handlers *cb)
1056 if (*ipcs == NULL) {
1057 crm_err(
"Failed to create pacemaker-attrd server: exiting and inhibiting respawn");
1058 crm_warn(
"Verify pacemaker and pacemaker_remote are not both enabled.");
1073 struct qb_ipcs_service_handlers *cb)
1078 if (*ipcs == NULL) {
1079 crm_err(
"Failed to create fencer: exiting and inhibiting respawn.");
1080 crm_warn(
"Verify pacemaker and pacemaker_remote are not both enabled.");
1087 #define MIN_MSG_SIZE 12336
1088 #define MAX_MSG_SIZE 128*1024
1094 unsigned int max_buf_size;
1096 unsigned int buf_size;
1102 qb_ipcc_connection_t *ipc;
1107 pick_ipc_buffer(
unsigned int max)
1109 static unsigned int global_max = 0;
1111 if (global_max == 0) {
1112 const char *env = getenv(
"PCMK_ipc_buffer");
1124 return QB_MAX(max, global_max);
1134 client->name = strdup(
name);
1135 client->buf_size = pick_ipc_buffer(max_size);
1136 client->buffer = malloc(client->buf_size);
1139 client->max_buf_size = client->buf_size;
1141 client->pfd.fd = -1;
1142 client->pfd.events = POLLIN;
1143 client->pfd.revents = 0;
1162 pid_t found_pid = 0; uid_t found_uid = 0; gid_t found_gid = 0;
1165 client->need_reply = FALSE;
1166 client->ipc = qb_ipcc_connect(client->name, client->buf_size);
1168 if (client->ipc == NULL) {
1174 if (client->pfd.fd < 0) {
1191 &found_pid, &found_uid,
1193 crm_err(
"Daemon (IPC %s) is not authentic:"
1194 " process %lld (uid: %lld, gid: %lld)",
1196 (
long long) found_uid, (
long long) found_gid);
1198 errno = ECONNABORTED;
1201 }
else if (rv < 0) {
1203 crm_perror(LOG_ERR,
"Could not verify authenticity of daemon (IPC %s)",
1210 qb_ipcc_context_set(client->ipc, client);
1212 #ifdef HAVE_IPCS_GET_BUFFER_SIZE
1213 client->max_buf_size = qb_ipcc_get_buffer_size(client->ipc);
1214 if (client->max_buf_size > client->buf_size) {
1215 free(client->buffer);
1216 client->buffer = calloc(1, client->max_buf_size);
1217 client->buf_size = client->max_buf_size;
1228 crm_trace(
"Disconnecting %s IPC connection %p (%p)", client->name, client, client->ipc);
1231 qb_ipcc_connection_t *ipc = client->ipc;
1234 qb_ipcc_disconnect(ipc);
1243 if (client->ipc && qb_ipcc_is_connected(client->ipc)) {
1244 crm_notice(
"Destroying an active IPC connection to %s", client->name);
1255 crm_trace(
"Destroying IPC connection to %s: %p", client->name, client);
1256 free(client->buffer);
1267 if (client && client->ipc && (qb_ipcc_fd_get(client->ipc, &fd) == 0)) {
1271 crm_perror(LOG_ERR,
"Could not obtain file IPC descriptor for %s",
1272 (client? client->name :
"unspecified client"));
1281 if (client == NULL) {
1285 }
else if (client->ipc == NULL) {
1289 }
else if (client->pfd.fd < 0) {
1294 rc = qb_ipcc_is_connected(client->ipc);
1296 client->pfd.fd = -EINVAL;
1319 client->pfd.revents = 0;
1320 rc = poll(&(client->pfd), 1, 0);
1321 return (
rc < 0)? -errno :
rc;
1328 struct crm_ipc_response_header *header = (
struct crm_ipc_response_header *)(
void*)client->buffer;
1330 if (header->size_compressed) {
1332 unsigned int size_u = 1 + header->size_uncompressed;
1334 unsigned int new_buf_size = QB_MAX((hdr_offset + size_u), client->max_buf_size);
1335 char *uncompressed = calloc(1, new_buf_size);
1337 crm_trace(
"Decompressing message data %u bytes into %u bytes",
1338 header->size_compressed, size_u);
1340 rc = BZ2_bzBuffToBuffDecompress(uncompressed + hdr_offset, &size_u,
1341 client->buffer + hdr_offset, header->size_compressed, 1, 0);
1358 CRM_ASSERT(size_u == header->size_uncompressed);
1360 memcpy(uncompressed, client->buffer, hdr_offset);
1361 header = (
struct crm_ipc_response_header *)(
void*)uncompressed;
1363 free(client->buffer);
1364 client->buf_size = new_buf_size;
1365 client->buffer = uncompressed;
1368 CRM_ASSERT(client->buffer[hdr_offset + header->size_uncompressed - 1] == 0);
1375 struct crm_ipc_response_header *header = NULL;
1383 client->buffer[0] = 0;
1384 client->msg_size = qb_ipcc_event_recv(client->ipc, client->buffer,
1385 client->buf_size, 0);
1386 if (client->msg_size >= 0) {
1387 int rc = crm_ipc_decompress(client);
1393 header = (
struct crm_ipc_response_header *)(
void*)client->buffer;
1395 crm_err(
"Filtering incompatible v%d IPC message, we only support versions <= %d",
1400 crm_trace(
"Received %s event %d, size=%u, rc=%d, text: %.100s",
1401 client->name, header->qb.id, header->qb.size, client->msg_size,
1402 client->buffer + hdr_offset);
1409 crm_err(
"Connection to %s failed", client->name);
1414 return header->size_uncompressed;
1423 return client->buffer +
sizeof(
struct crm_ipc_response_header);
1429 struct crm_ipc_response_header *header = NULL;
1432 if (client->buffer == NULL) {
1436 header = (
struct crm_ipc_response_header *)(
void*)client->buffer;
1437 return header->flags;
1444 return client->name;
1449 internal_ipc_get_reply(
crm_ipc_t *client,
int request_id,
int ms_timeout,
1452 time_t
timeout = time(NULL) + 1 + (ms_timeout / 1000);
1458 crm_trace(
"client %s waiting on reply to msg id %d", client->name, request_id);
1461 *bytes = qb_ipcc_recv(client->ipc, client->buffer, client->buf_size, 1000);
1463 struct crm_ipc_response_header *hdr = NULL;
1465 rc = crm_ipc_decompress(client);
1470 hdr = (
struct crm_ipc_response_header *)(
void*)client->buffer;
1471 if (hdr->qb.id == request_id) {
1474 }
else if (hdr->qb.id < request_id) {
1477 crm_err(
"Discarding old reply %d (need %d)", hdr->qb.id, request_id);
1483 crm_err(
"Discarding newer reply %d (need %d)", hdr->qb.id, request_id);
1488 crm_err(
"Server disconnected client %s while waiting for msg id %d", client->name,
1493 }
while (time(NULL) <
timeout);
1522 static uint32_t
id = 0;
1523 static int factor = 8;
1524 struct crm_ipc_response_header *header;
1528 if (client == NULL) {
1529 crm_notice(
"Can't send IPC request without connection (bug?): %.100s",
1535 crm_notice(
"Can't send IPC request to %s: Connection closed",
1540 if (ms_timeout == 0) {
1544 if (client->need_reply) {
1545 qb_rc = qb_ipcc_recv(client->ipc, client->buffer, client->buf_size, ms_timeout);
1547 crm_warn(
"Sending IPC to %s disabled until pending reply received",
1552 crm_notice(
"Sending IPC to %s re-enabled after pending reply received",
1554 client->need_reply = FALSE;
1562 crm_warn(
"Couldn't prepare IPC request to %s: %s " CRM_XS " rc=%d",
1567 header = iov[0].iov_base;
1568 header->flags |=
flags;
1575 if(header->size_compressed) {
1576 if(factor < 10 && (client->max_buf_size / 10) < (bytes / factor)) {
1577 crm_notice(
"Compressed message exceeds %d0%% of configured IPC "
1578 "limit (%u bytes); consider setting PCMK_ipc_buffer to "
1580 factor, client->max_buf_size, 2 * client->max_buf_size);
1585 crm_trace(
"Sending %s IPC request %d of %u bytes using %dms timeout",
1586 client->name, header->qb.id, header->qb.size, ms_timeout);
1590 time_t
timeout = time(NULL) + 1 + (ms_timeout / 1000);
1600 qb_rc = qb_ipcc_sendv(client->ipc, iov, 2);
1601 }
while ((qb_rc == -EAGAIN) && (time(NULL) <
timeout));
1608 crm_trace(
"Not waiting for reply to %s IPC request %d",
1609 client->name, header->qb.id);
1613 rc = internal_ipc_get_reply(client, header->qb.id, ms_timeout, &bytes);
1621 client->need_reply = TRUE;
1628 qb_rc = qb_ipcc_sendv_recv(client->ipc, iov, 2, client->buffer,
1629 client->buf_size, -1);
1635 struct crm_ipc_response_header *hdr = (
struct crm_ipc_response_header *)(
void*)client->buffer;
1637 crm_trace(
"Received %d-byte reply %d to %s IPC %d: %.100s",
1638 rc, hdr->qb.id, client->name, header->qb.id,
1646 crm_trace(
"No reply to %s IPC %d: rc=%d",
1647 client->name, header->qb.id,
rc);
1652 crm_notice(
"Couldn't send %s IPC request %d: Connection closed "
1653 CRM_XS " rc=%d", client->name, header->qb.id,
rc);
1655 }
else if (
rc == -ETIMEDOUT) {
1656 crm_warn(
"%s IPC request %d failed: %s after %dms " CRM_XS " rc=%d",
1661 }
else if (
rc <= 0) {
1663 client->name, header->qb.id,
1673 pid_t *gotpid, uid_t *gotuid, gid_t *gotgid) {
1675 pid_t found_pid = 0; uid_t found_uid = 0; gid_t found_gid = 0;
1676 #if defined(US_AUTH_PEERCRED_UCRED)
1678 socklen_t ucred_len =
sizeof(ucred);
1680 if (!getsockopt(sock, SOL_SOCKET, SO_PEERCRED,
1682 && ucred_len ==
sizeof(ucred)) {
1683 found_pid = ucred.pid; found_uid = ucred.uid; found_gid = ucred.gid;
1685 #elif defined(US_AUTH_PEERCRED_SOCKPEERCRED)
1686 struct sockpeercred sockpeercred;
1687 socklen_t sockpeercred_len =
sizeof(sockpeercred);
1689 if (!getsockopt(sock, SOL_SOCKET, SO_PEERCRED,
1690 &sockpeercred, &sockpeercred_len)
1691 && sockpeercred_len ==
sizeof(sockpeercred_len)) {
1692 found_pid = sockpeercred.pid;
1693 found_uid = sockpeercred.uid; found_gid = sockpeercred.gid;
1695 #elif defined(US_AUTH_GETPEEREID)
1696 if (!getpeereid(sock, &found_uid, &found_gid)) {
1699 #elif defined(US_AUTH_GETPEERUCRED)
1701 if (!getpeerucred(sock, &ucred)) {
1703 found_pid = ucred_getpid(ucred);
1704 found_uid = ucred_geteuid(ucred); found_gid = ucred_getegid(ucred);
1712 # error "No way to authenticate a Unix socket peer"
1716 if (gotpid != NULL) {
1717 *gotpid = found_pid;
1719 if (gotuid != NULL) {
1720 *gotuid = found_uid;
1722 if (gotgid != NULL) {
1723 *gotgid = found_gid;
1725 ret = (found_uid == 0 || found_uid == refuid || found_gid == refgid);
1735 gid_t refgid, pid_t *gotpid)
1737 static char last_asked_name[PATH_MAX / 2] =
"";
1742 pid_t found_pid = 0; uid_t found_uid = 0; gid_t found_gid = 0;
1743 qb_ipcc_connection_t *c;
1745 c = qb_ipcc_connect(
name, 0);
1752 qb_rc = qb_ipcc_fd_get(c, &fd);
1755 crm_err(
"Could not get fd from %s IPC: %s " CRM_XS " rc=%d",
1761 &found_uid, &found_gid);
1764 crm_err(
"Could not get peer credentials from %s IPC: %s "
1769 if (gotpid != NULL) {
1770 *gotpid = found_pid;
1774 crm_err(
"Daemon (IPC %s) effectively blocked with unauthorized"
1775 " process %lld (uid: %lld, gid: %lld)",
1777 (
long long) found_uid, (
long long) found_gid);
1783 if ((found_uid != refuid || found_gid != refgid)
1784 && strncmp(last_asked_name,
name,
sizeof(last_asked_name))) {
1785 if ((found_uid == 0) && (refuid != 0)) {
1786 crm_warn(
"Daemon (IPC %s) runs as root, whereas the expected"
1787 " credentials are %lld:%lld, hazard of violating"
1788 " the least privilege principle",
1789 name, (
long long) refuid, (
long long) refgid);
1791 crm_notice(
"Daemon (IPC %s) runs as %lld:%lld, whereas the"
1792 " expected credentials are %lld:%lld, which may"
1793 " mean a different set of privileges than expected",
1794 name, (
long long) found_uid, (
long long) found_gid,
1795 (
long long) refuid, (
long long) refgid);
1797 memccpy(last_asked_name,
name,
'\0',
sizeof(last_asked_name));
1802 qb_ipcc_disconnect(c);
1812 const char *client_name,
const char *major_version,
const char *minor_version)
1814 xmlNode *hello_node = NULL;
1815 xmlNode *hello = NULL;
1817 if (pcmk__str_empty(uuid) || pcmk__str_empty(client_name)
1818 || pcmk__str_empty(major_version) || pcmk__str_empty(minor_version)) {
1819 crm_err(
"Could not create IPC hello message from %s (UUID %s): "
1820 "missing information",
1821 client_name? client_name :
"unknown client",
1822 uuid? uuid :
"unknown");
1827 if (hello_node == NULL) {
1828 crm_err(
"Could not create IPC hello message from %s (UUID %s): "
1829 "Message data creation failed", client_name, uuid);
1833 crm_xml_add(hello_node,
"major_version", major_version);
1834 crm_xml_add(hello_node,
"minor_version", minor_version);
1835 crm_xml_add(hello_node,
"client_name", client_name);
1839 if (hello == NULL) {
1840 crm_err(
"Could not create IPC hello message from %s (UUID %s): "
1841 "Request creation failed", client_name, uuid);
1846 crm_trace(
"Created hello message from %s (UUID %s)", client_name, uuid);
enum crm_ais_msg_types type
char * pcmk__uid2username(uid_t uid)
#define pcmk__plural_s(i)
int pcmk__compress(const char *data, unsigned int length, unsigned int max, char **result, unsigned int *result_len)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
int pcmk_daemon_user(uid_t *uid, gid_t *gid)
Get user and group IDs of pacemaker daemon user.
char * crm_generate_uuid(void)
long long crm_parse_ll(const char *text, const char *default_text)
Parse a long long integer value from a string.
int crm_parse_int(const char *text, const char *default_text)
Parse an integer value from a string.
#define PCMK__SERVER_BASED_RO
#define clear_bit(word, bit)
#define PCMK__SERVER_BASED_RW
#define PCMK__SERVER_BASED_SHM
char * generate_hash_key(const char *crm_msg_reference, const char *sys)
#define set_bit(word, bit)
xmlNode * create_hello_message(const char *uuid, const char *client_name, const char *major_version, const char *minor_version)
void crm_ipc_destroy(crm_ipc_t *client)
xmlNode * pcmk__client_data2xml(pcmk__client_t *c, void *data, uint32_t *id, uint32_t *flags)
int crm_ipc_send(crm_ipc_t *client, xmlNode *message, enum crm_ipc_flags flags, int32_t ms_timeout, xmlNode **reply)
Send an IPC XML message.
pcmk__client_t * pcmk__new_unauth_client(void *key)
Allocate a new pcmk__client_t object and generate its ID.
void pcmk__ipc_send_ack_as(const char *function, int line, pcmk__client_t *c, uint32_t request, uint32_t flags, const char *tag)
pcmk__client_t * pcmk__find_client(qb_ipcs_connection_t *c)
int pcmk__client_pid(qb_ipcs_connection_t *c)
#define PCMK_IPC_DEFAULT_QUEUE_MAX
const char * crm_ipc_buffer(crm_ipc_t *client)
int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, xmlNode *message, uint32_t flags)
long crm_ipc_read(crm_ipc_t *client)
const char * pcmk__client_type_str(enum pcmk__client_type client_type)
int crm_ipc_get_fd(crm_ipc_t *client)
unsigned int crm_ipc_default_buffer_size(void)
qb_ipcs_service_t * pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb)
void pcmk_free_ipc_event(struct iovec *event)
Free an I/O vector created by pcmk__ipc_prepare_iov()
int crm_ipc_ready(crm_ipc_t *client)
Check whether an IPC connection is ready to be read.
const char * pcmk__client_name(pcmk__client_t *c)
xmlNode * create_request_adv(const char *task, xmlNode *msg_data, const char *host_to, const char *sys_to, const char *sys_from, const char *uuid_from, const char *origin)
bool crm_ipc_connected(crm_ipc_t *client)
void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
bool crm_ipc_connect(crm_ipc_t *client)
Establish an IPC connection to a Pacemaker component.
xmlNode * create_reply_adv(xmlNode *original_request, xmlNode *xml_response_data, const char *origin)
int crm_ipc_is_authentic_process(int sock, uid_t refuid, gid_t refgid, pid_t *gotpid, uid_t *gotuid, gid_t *gotgid)
Check the authenticity of the IPC socket peer process.
void pcmk__stop_based_ipc(qb_ipcs_service_t *ipcs_ro, qb_ipcs_service_t *ipcs_rw, qb_ipcs_service_t *ipcs_shm)
void crm_ipc_close(crm_ipc_t *client)
pcmk__client_t * pcmk__find_client_by_id(const char *id)
void pcmk__free_client(pcmk__client_t *c)
int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid, gid_t refgid, pid_t *gotpid)
crm_ipc_t * crm_ipc_new(const char *name, size_t max_size)
guint pcmk__ipc_client_count()
uint32_t crm_ipc_buffer_flags(crm_ipc_t *client)
bool pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax)
void pcmk__serve_based_ipc(qb_ipcs_service_t **ipcs_ro, qb_ipcs_service_t **ipcs_rw, qb_ipcs_service_t **ipcs_shm, struct qb_ipcs_service_handlers *ro_cb, struct qb_ipcs_service_handlers *rw_cb)
void pcmk__foreach_ipc_client_remove(GHRFunc func, gpointer user_data)
void pcmk__client_cleanup(void)
int pcmk__ipc_prepare_iov(uint32_t request, xmlNode *message, uint32_t max_send_size, struct iovec **result, ssize_t *bytes)
void pcmk__drop_all_clients(qb_ipcs_service_t *service)
const char * crm_ipc_name(crm_ipc_t *client)
void pcmk__foreach_ipc_client(GHFunc func, gpointer user_data)
int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags)
void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
pcmk__client_t * pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid_client, gid_t gid_client)
Wrappers for and extensions to libqb IPC.
#define create_request(task, xml_data, host_to, sys_to, sys_from, uuid_from)
@ crm_ipc_proxied_relay_response
@ crm_ipc_client_response
struct crm_ipc_s crm_ipc_t
#define PCMK__SPECIAL_PID_AS_0(p)
#define PCMK__SPECIAL_PID
@ pcmk__client_privileged
#define crm_info(fmt, args...)
#define crm_warn(fmt, args...)
#define CRM_LOG_ASSERT(expr)
#define crm_notice(fmt, args...)
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
#define CRM_CHECK(expr, failure_action)
void crm_write_blackbox(int nsig, struct qb_log_callsite *callsite)
#define crm_debug(fmt, args...)
#define crm_err(fmt, args...)
#define crm_log_xml_trace(xml, text)
#define crm_trace(fmt, args...)
#define crm_log_xml_notice(xml, text)
qb_ipcs_service_t * mainloop_add_ipc_server_with_prio(const char *name, enum qb_ipc_type type, struct qb_ipcs_service_handlers *callbacks, enum qb_loop_priority prio)
Start server-side API end-point, hooked into the internal event loop.
qb_ipcs_service_t * mainloop_add_ipc_server(const char *name, enum qb_ipc_type type, struct qb_ipcs_service_handlers *callbacks)
#define XML_ATTR_RESPONSE
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
char * strerror(int errnum)
const char * bz2_strerror(int rc)
_Noreturn crm_exit_t crm_exit(crm_exit_t rc)
@ pcmk_rc_ipc_unauthorized
@ pcmk_rc_ipc_unresponsive
const char * pcmk_strerror(int rc)
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
int pcmk_rc2legacy(int rc)
int pcmk_legacy2rc(int legacy_rc)
qb_ipcs_connection_t * ipcs
unsigned int queue_backlog
struct pcmk__remote_s * remote
enum pcmk__client_type kind
gboolean add_message_xml(xmlNode *msg, const char *field, xmlNode *xml)
char * dump_xml_unformatted(xmlNode *msg)
void free_xml(xmlNode *child)
xmlNode * create_xml_node(xmlNode *parent, const char *name)
xmlNode * string2xml(const char *input)