Signed-off-by: Angus Salkeld asalkeld@redhat.com --- include/qb/qbipcs.h | 18 ++++++++++++ include/qb/qbrb.h | 8 ++++++ lib/ipc_int.h | 7 +++++ lib/ipc_shm.c | 80 ++++++++++++++++++++++++++------------------------- lib/ipc_us.c | 5 ++-- lib/ipcs.c | 11 +++++++ lib/ringbuffer.c | 19 ++++++++++++ 7 files changed, 107 insertions(+), 41 deletions(-)
diff --git a/include/qb/qbipcs.h b/include/qb/qbipcs.h index 2bbe22e..ff0931b 100644 --- a/include/qb/qbipcs.h +++ b/include/qb/qbipcs.h @@ -117,6 +117,8 @@ struct qb_ipcs_poll_handlers { * The type of checks you should do are authentication, service availabilty * or process resource constraints. * @return 0 to accept or -errno to indicate a failure (sent back to the client) + * + * @note you can call qb_ipcs_connection_auth_set() within this function. */ typedef int32_t (*qb_ipcs_connection_accept_fn) (qb_ipcs_connection_t *c, uid_t uid, gid_t gid); @@ -377,6 +379,22 @@ qb_ipcs_connection_t * qb_ipcs_connection_first_get(qb_ipcs_service_t* pt); qb_ipcs_connection_t * qb_ipcs_connection_next_get(qb_ipcs_service_t* pt, qb_ipcs_connection_t *current);
+/** + * Set the permissions on and shared memory files so that both processes can + * read and write to them. + * + * @param uid the user id to set. + * @param gid the group id to set. + * @param mode the mode to set. + * + * @see chmod() chown() + * @note this must be called within the qb_ipcs_connection_accept_fn() + * callback. + */ +void qb_ipcs_connection_auth_set(qb_ipcs_connection_t *conn, uid_t uid, + gid_t gid, mode_t mode); + + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/include/qb/qbrb.h b/include/qb/qbrb.h index 8a012bd..fd37626 100644 --- a/include/qb/qbrb.h +++ b/include/qb/qbrb.h @@ -285,6 +285,14 @@ qb_ringbuffer_t *qb_rb_create_from_file(int32_t fd, uint32_t flags); */ int32_t qb_rb_chown(qb_ringbuffer_t * rb, uid_t owner, gid_t group);
+/** + * Like 'chmod' it changes the mode of the ringbuffers resources. + * @param mode mode to change to + * @param rb ringbuffer instance + * @retval 0 == ok + * @retval -errno for error + */ +int32_t qb_rb_chmod(qb_ringbuffer_t * rb, mode_t mode);
/* *INDENT-OFF* */ #ifdef __cplusplus diff --git a/lib/ipc_int.h b/lib/ipc_int.h index a569a80..14f2091 100644 --- a/lib/ipc_int.h +++ b/lib/ipc_int.h @@ -156,12 +156,19 @@ enum qb_ipcs_connection_state {
#define CONNECTION_DESCRIPTION (16)
+struct qb_ipcs_connection_auth { + uid_t uid; + gid_t gid; + mode_t mode; +}; + struct qb_ipcs_connection { enum qb_ipcs_connection_state state; int32_t refcount; pid_t pid; uid_t euid; gid_t egid; + struct qb_ipcs_connection_auth auth; struct qb_ipc_one_way setup; struct qb_ipc_one_way request; struct qb_ipc_one_way response; diff --git a/lib/ipc_shm.c b/lib/ipc_shm.c index 19c9788..3e823ea 100644 --- a/lib/ipc_shm.c +++ b/lib/ipc_shm.c @@ -234,6 +234,40 @@ qb_ipcs_shm_disconnect(struct qb_ipcs_connection *c) }
static int32_t +qb_ipcs_shm_rb_open(struct qb_ipcs_connection *c, + struct qb_ipc_one_way *ow, + const char *rb_name) +{ + int32_t res = 0; + + ow->u.shm.rb = qb_rb_open(rb_name, + ow->max_msg_size, + QB_RB_FLAG_CREATE | + QB_RB_FLAG_SHARED_PROCESS, + sizeof(int32_t)); + if (ow->u.shm.rb == NULL) { + res = -errno; + qb_util_perror(LOG_ERR, "qb_rb_open:%s", rb_name); + return res; + } + res = qb_rb_chown(ow->u.shm.rb, c->auth.uid, c->auth.gid); + if (res != 0) { + qb_util_perror(LOG_ERR, "qb_rb_chown:%s", rb_name); + goto cleanup; + } + res = qb_rb_chmod(ow->u.shm.rb, c->auth.mode); + if (res != 0) { + qb_util_perror(LOG_ERR, "qb_rb_chmod:%s", rb_name); + goto cleanup; + } + return res; + +cleanup: + qb_rb_close(ow->u.shm.rb); + return res; +} + +static int32_t qb_ipcs_shm_connect(struct qb_ipcs_service *s, struct qb_ipcs_connection *c, struct qb_ipc_connection_response *r) @@ -249,59 +283,27 @@ qb_ipcs_shm_connect(struct qb_ipcs_service *s, snprintf(r->event, NAME_MAX, "%s-event-%s", s->name, c->description);
- c->request.u.shm.rb = qb_rb_open(r->request, - c->request.max_msg_size, - QB_RB_FLAG_CREATE | - QB_RB_FLAG_SHARED_PROCESS, - sizeof(int32_t)); - if (c->request.u.shm.rb == NULL) { - res = -errno; - qb_util_perror(LOG_ERR, "qb_rb_open:%s", r->request); - goto cleanup; - } - res = qb_rb_chown(c->request.u.shm.rb, c->euid, c->egid); + res = qb_ipcs_shm_rb_open(c, &c->request, + r->request); if (res != 0) { - qb_util_perror(LOG_ERR, "qb_rb_chown:%s", r->request); goto cleanup; }
- c->response.u.shm.rb = qb_rb_open(r->response, - c->response.max_msg_size, - QB_RB_FLAG_CREATE | - QB_RB_FLAG_SHARED_PROCESS, 0); - if (c->response.u.shm.rb == NULL) { - res = -errno; - qb_util_perror(LOG_ERR, "qb_rb_open:%s", r->response); - goto cleanup_request; - } - res = qb_rb_chown(c->response.u.shm.rb, c->euid, c->egid); + res = qb_ipcs_shm_rb_open(c, &c->response, + r->response); if (res != 0) { - qb_util_perror(LOG_ERR, "qb_rb_chown:%s", r->response); goto cleanup_request; }
- c->event.u.shm.rb = qb_rb_open(r->event, - c->event.max_msg_size, - QB_RB_FLAG_CREATE | - QB_RB_FLAG_SHARED_PROCESS, 0); - - if (c->event.u.shm.rb == NULL) { - res = -errno; - qb_util_perror(LOG_ERR, "qb_rb_open:%s", r->event); - goto cleanup_request_response; - } - res = qb_rb_chown(c->event.u.shm.rb, c->euid, c->egid); + res = qb_ipcs_shm_rb_open(c, &c->event, + r->event); if (res != 0) { - qb_util_perror(LOG_ERR, "qb_rb_chown:%s", r->event); - goto cleanup_all; + goto cleanup_request_response; }
r->hdr.error = 0; return 0;
-cleanup_all: - qb_rb_close(c->event.u.shm.rb); - cleanup_request_response: qb_rb_close(c->request.u.shm.rb);
diff --git a/lib/ipc_us.c b/lib/ipc_us.c index 2808708..73c4392 100644 --- a/lib/ipc_us.c +++ b/lib/ipc_us.c @@ -615,8 +615,9 @@ handle_new_connection(struct qb_ipcs_service *s, c->response.max_msg_size = req->max_msg_size; c->event.max_msg_size = req->max_msg_size; c->pid = ugp->pid; - c->euid = ugp->uid; - c->egid = ugp->gid; + c->auth.uid = c->euid = ugp->uid; + c->auth.gid = c->egid = ugp->gid; + c->auth.mode = 0600; c->stats.client_pid = ugp->pid; snprintf(c->description, CONNECTION_DESCRIPTION, "%d-%d-%d", s->pid, ugp->pid, diff --git a/lib/ipcs.c b/lib/ipcs.c index 8370c7d..68cb0a8 100644 --- a/lib/ipcs.c +++ b/lib/ipcs.c @@ -864,3 +864,14 @@ qb_ipcs_stats_get(struct qb_ipcs_service * s, } return 0; } + +void +qb_ipcs_connection_auth_set(qb_ipcs_connection_t *c, uid_t uid, + gid_t gid, mode_t mode) +{ + if (c) { + c->auth.uid = uid; + c->auth.gid = gid; + c->auth.mode = mode; + } +} diff --git a/lib/ringbuffer.c b/lib/ringbuffer.c index 1daa0a9..7902dcd 100644 --- a/lib/ringbuffer.c +++ b/lib/ringbuffer.c @@ -769,3 +769,22 @@ qb_rb_chown(struct qb_ringbuffer_s * rb, uid_t owner, gid_t group) } return 0; } + +int32_t +qb_rb_chmod(qb_ringbuffer_t * rb, mode_t mode) +{ + int32_t res; + + if (rb == NULL) { + return -EINVAL; + } + res = chmod(rb->shared_hdr->data_path, mode); + if (res < 0) { + return -errno; + } + res = chmod(rb->shared_hdr->hdr_path, mode); + if (res < 0) { + return -errno; + } + return 0; +}