root/include/crm/common/ipc.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


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

/* [previous][next][first][last][top][bottom][index][help] */