1 /* 2 * Copyright 2004-2024 the Pacemaker project contributors 3 * 4 * The version control history for this file may have further details. 5 * 6 * This source code is licensed under the GNU Lesser General Public License 7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. 8 */ 9 10 #ifndef PCMK__CRM_COMMON_IPC__H 11 #define PCMK__CRM_COMMON_IPC__H 12 13 14 #include <sys/uio.h> 15 #include <qb/qbipcc.h> 16 #include <crm/common/xml.h> 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 22 /** 23 * \file 24 * \brief IPC interface to Pacemaker daemons 25 * 26 * \ingroup core 27 */ 28 29 /* 30 * Message creation utilities 31 * 32 * These are used for both IPC messages and cluster layer messages. However, 33 * since this is public API, they stay in this header for backward 34 * compatibility. 35 */ 36 37 // @COMPAT Make internal when we can break API backward compatibility 38 //! \deprecated Do not use 39 #define create_reply(request, xml_response_data) \ 40 create_reply_adv(request, xml_response_data, __func__) 41 42 // @COMPAT Make internal when we can break API backward compatibility 43 //! \deprecated Do not use 44 xmlNode *create_reply_adv(const xmlNode *request, xmlNode *xml_response_data, 45 const char *origin); 46 47 // @COMPAT Make internal when we can break API backward compatibility 48 //! \deprecated Do not use 49 #define create_request(task, xml_data, host_to, sys_to, sys_from, uuid_from) \ 50 create_request_adv(task, xml_data, host_to, sys_to, sys_from, uuid_from, \ 51 __func__) 52 53 // @COMPAT Make internal when we can break API backward compatibility 54 //! \deprecated Do not use 55 xmlNode *create_request_adv(const char *task, xmlNode *xml_data, 56 const char *host_to, const char *sys_to, 57 const char *sys_from, const char *uuid_from, 58 const char *origin); 59 60 61 /* 62 * The library supports two methods of creating IPC connections. The older code 63 * allows connecting to any arbitrary IPC name. The newer code only allows 64 * connecting to one of the Pacemaker daemons. 65 * 66 * As daemons are converted to use the new model, the old functions should be 67 * considered deprecated for use with those daemons. Once all daemons are 68 * converted, the old functions should be officially deprecated as public API 69 * and eventually made internal API. 70 */ 71 72 /* 73 * Pacemaker daemon IPC 74 */ 75 76 //! Available IPC interfaces 77 enum pcmk_ipc_server { 78 pcmk_ipc_attrd, //!< Attribute manager 79 pcmk_ipc_based, //!< CIB manager 80 pcmk_ipc_controld, //!< Controller 81 pcmk_ipc_execd, //!< Executor 82 pcmk_ipc_fenced, //!< Fencer 83 pcmk_ipc_pacemakerd, //!< Launcher 84 pcmk_ipc_schedulerd, //!< Scheduler 85 }; 86 87 // NOTE: sbd (as of at least 1.5.2) uses this enum 88 //! Possible event types that an IPC event callback can be called for 89 enum pcmk_ipc_event { 90 pcmk_ipc_event_connect, //!< Result of asynchronous connection attempt 91 92 // NOTE: sbd (as of at least 1.5.2) uses this value 93 pcmk_ipc_event_disconnect, //!< Termination of IPC connection 94 95 // NOTE: sbd (as of at least 1.5.2) uses this value 96 pcmk_ipc_event_reply, //!< Daemon's reply to client IPC request 97 98 pcmk_ipc_event_notify, //!< Notification from daemon 99 }; 100 101 //! How IPC replies should be dispatched 102 enum pcmk_ipc_dispatch { 103 pcmk_ipc_dispatch_main, //!< Attach IPC to GMainLoop for dispatch 104 pcmk_ipc_dispatch_poll, //!< Caller will poll and dispatch IPC 105 pcmk_ipc_dispatch_sync, //!< Sending a command will wait for any reply 106 }; 107 108 // NOTE: sbd (as of at least 1.5.2) uses this 109 //! Client connection to Pacemaker IPC 110 typedef struct pcmk_ipc_api_s pcmk_ipc_api_t; 111 112 /*! 113 * \brief Callback function type for Pacemaker daemon IPC APIs 114 * 115 * \param[in,out] api IPC API connection 116 * \param[in] event_type The type of event that occurred 117 * \param[in] status Event status 118 * \param[in,out] event_data Event-specific data 119 * \param[in,out] user_data Caller data provided when callback was registered 120 * 121 * \note For connection and disconnection events, event_data may be NULL (for 122 * local IPC) or the name of the connected node (for remote IPC, for 123 * daemons that support that). For reply and notify events, event_data is 124 * defined by the specific daemon API. 125 */ 126 typedef void (*pcmk_ipc_callback_t)(pcmk_ipc_api_t *api, 127 enum pcmk_ipc_event event_type, 128 crm_exit_t status, 129 void *event_data, void *user_data); 130 131 // NOTE: sbd (as of at least 1.5.2) uses this 132 int pcmk_new_ipc_api(pcmk_ipc_api_t **api, enum pcmk_ipc_server server); 133 134 // NOTE: sbd (as of at least 1.5.2) uses this 135 void pcmk_free_ipc_api(pcmk_ipc_api_t *api); 136 137 // NOTE: sbd (as of at least 1.5.2) uses this 138 int pcmk_connect_ipc(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type); 139 140 void pcmk_disconnect_ipc(pcmk_ipc_api_t *api); 141 142 int pcmk_poll_ipc(const pcmk_ipc_api_t *api, int timeout_ms); 143 144 void pcmk_dispatch_ipc(pcmk_ipc_api_t *api); 145 146 // NOTE: sbd (as of at least 1.5.2) uses this 147 void pcmk_register_ipc_callback(pcmk_ipc_api_t *api, pcmk_ipc_callback_t cb, 148 void *user_data); 149 150 const char *pcmk_ipc_name(const pcmk_ipc_api_t *api, bool for_log); 151 152 bool pcmk_ipc_is_connected(pcmk_ipc_api_t *api); 153 154 int pcmk_ipc_purge_node(pcmk_ipc_api_t *api, const char *node_name, 155 uint32_t nodeid); 156 157 158 /* 159 * Generic IPC API (to eventually be deprecated as public API and made internal) 160 */ 161 162 /* *INDENT-OFF* */ 163 enum crm_ipc_flags 164 { 165 crm_ipc_flags_none = 0x00000000, 166 167 crm_ipc_compressed = 0x00000001, /* Message has been compressed */ 168 169 crm_ipc_proxied = 0x00000100, /* _ALL_ replies to proxied connections need to be sent as events */ 170 crm_ipc_client_response = 0x00000200, /* A Response is expected in reply */ 171 172 // These are options for Pacemaker's internal use only (pcmk__ipc_send_*()) 173 crm_ipc_server_event = 0x00010000, /* Send an Event instead of a Response */ 174 crm_ipc_server_free = 0x00020000, /* Free the iovec after sending */ 175 crm_ipc_proxied_relay_response = 0x00040000, /* all replies to proxied connections are sent as events, this flag preserves whether the event should be treated as an actual event, or a response.*/ 176 177 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1) 178 crm_ipc_server_info = 0x00100000, //!< \deprecated Unused 179 crm_ipc_server_error = 0x00200000, //!< \deprecated Unused 180 #endif 181 }; 182 /* *INDENT-ON* */ 183 184 typedef struct crm_ipc_s crm_ipc_t; 185 186 crm_ipc_t *crm_ipc_new(const char *name, size_t max_size); 187 bool crm_ipc_connect(crm_ipc_t * client); 188 void crm_ipc_close(crm_ipc_t * client); 189 void crm_ipc_destroy(crm_ipc_t * client); 190 void pcmk_free_ipc_event(struct iovec *event); 191 192 int crm_ipc_send(crm_ipc_t *client, const xmlNode *message, 193 enum crm_ipc_flags flags, int32_t ms_timeout, xmlNode **reply); 194 195 int crm_ipc_get_fd(crm_ipc_t * client); 196 bool crm_ipc_connected(crm_ipc_t * client); 197 int crm_ipc_ready(crm_ipc_t * client); 198 long crm_ipc_read(crm_ipc_t * client); 199 const char *crm_ipc_buffer(crm_ipc_t * client); 200 uint32_t crm_ipc_buffer_flags(crm_ipc_t * client); 201 const char *crm_ipc_name(crm_ipc_t * client); 202 unsigned int crm_ipc_default_buffer_size(void); 203 204 /*! 205 * \brief Check the authenticity of the IPC socket peer process (legacy) 206 * 207 * If everything goes well, peer's authenticity is verified by the means 208 * of comparing against provided referential UID and GID (either satisfies), 209 * and the result of this check can be deduced from the return value. 210 * As an exception, detected UID of 0 ("root") satisfies arbitrary 211 * provided referential daemon's credentials. 212 * 213 * \param[in] sock IPC related, connected Unix socket to check peer of 214 * \param[in] refuid referential UID to check against 215 * \param[in] refgid referential GID to check against 216 * \param[out] gotpid to optionally store obtained PID of the peer 217 * (not available on FreeBSD, special value of 1 218 * used instead, and the caller is required to 219 * special case this value respectively) 220 * \param[out] gotuid to optionally store obtained UID of the peer 221 * \param[out] gotgid to optionally store obtained GID of the peer 222 * 223 * \return 0 if IPC related socket's peer is not authentic given the 224 * referential credentials (see above), 1 if it is, 225 * negative value on error (generally expressing -errno unless 226 * it was zero even on nonhappy path, -pcmk_err_generic is 227 * returned then; no message is directly emitted) 228 * 229 * \note While this function is tolerant on what constitutes authorized 230 * IPC daemon process (its effective user matches UID=0 or \p refuid, 231 * or at least its group matches \p refgid), either or both (in case 232 * of UID=0) mismatches on the expected credentials of such peer 233 * process \e shall be investigated at the caller when value of 1 234 * gets returned there, since higher-than-expected privileges in 235 * respect to the expected/intended credentials possibly violate 236 * the least privilege principle and may pose an additional risk 237 * (i.e. such accidental inconsistency shall be eventually fixed). 238 */ 239 int crm_ipc_is_authentic_process(int sock, uid_t refuid, gid_t refgid, 240 pid_t *gotpid, uid_t *gotuid, gid_t *gotgid); 241 242 // @COMPAT Make internal when we can break API backward compatibility 243 //! \deprecated Do not use 244 xmlNode *create_hello_message(const char *uuid, const char *client_name, 245 const char *major_version, const char *minor_version); 246 247 #ifdef __cplusplus 248 } 249 #endif 250 251 #endif