Yan, can you test and tell me if this fixes your problem?
If it does I'll push the change.
Regards
Angus
On 12/06/12 10:25 +1000, Angus Salkeld wrote:
Signed-off-by: Angus Salkeld <asalkeld(a)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;
+}
--
1.7.10.2