ipc: set gid on unix sockets

When creating a unix socket it's default gid is that of the parent
directory.  If the SOCKETDIR is owned by root:wheel with 1777 mode
some of the pacemaker daemons end up unable to communicate with one
another due to having insufficient permissions on the sockets.

This can be fixed by setting the client sockets gid to the primary
group of the server socket owner it's attempting to connect to.  And,
on the server side by setting the gid to the already captured gid
stored in the connection info.  This ensures that regardless of who
owns the socket directory, as long as the applications have r/w
access to it they should work.
This commit is contained in:
David Shane Holden 2016-01-22 20:00:57 -05:00
parent 267160634d
commit 8668d051c5

View File

@ -60,7 +60,8 @@ set_sock_addr(struct sockaddr_un *address, const char *socket_name)
static int32_t
qb_ipc_dgram_sock_setup(const char *base_name,
const char *service_name, int32_t * sock_pt)
const char *service_name, int32_t * sock_pt,
gid_t gid)
{
int32_t request_fd;
struct sockaddr_un local_address;
@ -86,6 +87,7 @@ qb_ipc_dgram_sock_setup(const char *base_name,
sizeof(local_address));
#if !(defined(QB_LINUX) || defined(QB_CYGWIN))
chmod(local_address.sun_path, 0660);
chown(local_address.sun_path, getuid(), gid);
#endif
if (res < 0) {
goto error_connect;
@ -221,12 +223,12 @@ static int32_t
qb_ipc_dgram_sock_connect(const char *base_name,
const char *local_name,
const char *remote_name,
int32_t max_msg_size, int32_t * sock_pt)
int32_t max_msg_size, int32_t * sock_pt, gid_t gid)
{
char sock_path[PATH_MAX];
struct sockaddr_un remote_address;
int32_t res = qb_ipc_dgram_sock_setup(base_name, local_name,
sock_pt);
sock_pt, gid);
if (res < 0) {
return res;
}
@ -547,14 +549,14 @@ qb_ipcc_us_connect(struct qb_ipcc_connection * c,
fd_hdr = -1;
res = qb_ipc_dgram_sock_connect(r->response, "response", "request",
r->max_msg_size, &c->request.u.us.sock);
r->max_msg_size, &c->request.u.us.sock, c->egid);
if (res != 0) {
goto cleanup_hdr;
}
c->response.u.us.sock = c->request.u.us.sock;
res = qb_ipc_dgram_sock_connect(r->response, "event", "event-tx",
r->max_msg_size, &c->event.u.us.sock);
r->max_msg_size, &c->event.u.us.sock, c->egid);
if (res != 0) {
goto cleanup_hdr;
}
@ -776,7 +778,7 @@ qb_ipcs_us_connect(struct qb_ipcs_service *s,
/* request channel */
res = qb_ipc_dgram_sock_setup(r->response, "request",
&c->request.u.us.sock);
&c->request.u.us.sock, c->egid);
if (res < 0) {
goto cleanup_hdr;
}
@ -790,7 +792,7 @@ qb_ipcs_us_connect(struct qb_ipcs_service *s,
/* event channel */
res = qb_ipc_dgram_sock_setup(r->response, "event-tx",
&c->event.u.us.sock);
&c->event.u.us.sock, c->egid);
if (res < 0) {
goto cleanup_hdr;
}