diff --git a/include/qb/qbipcc.h b/include/qb/qbipcc.h index 5bf14cf83..de96c7289 100644 --- a/include/qb/qbipcc.h +++ b/include/qb/qbipcc.h @@ -109,6 +109,17 @@ void qb_ipcc_disconnect(qb_ipcc_connection_t* c); */ int32_t qb_ipcc_fd_get(qb_ipcc_connection_t* c, int32_t * fd); +/** + * Get the credentials of the server process + * + * + * @param c connection instance + * @param pid PID of the server we are connected to + * @param uid UID of the server we are connected to + * @param gid GID of the server we are connected to + */ +int32_t qb_ipcc_auth_get(qb_ipcc_connection_t* c, pid_t *pid, uid_t *uid, gid_t *gid); + /** * Set the maximum allowable flowcontrol value. * diff --git a/lib/ipc_int.h b/lib/ipc_int.h index 70f7d17a1..03c5dabbb 100644 --- a/lib/ipc_int.h +++ b/lib/ipc_int.h @@ -102,6 +102,7 @@ struct qb_ipcc_connection { uint32_t fc_enable_max; int32_t is_connected; void * context; + uid_t euid; }; int32_t qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c, diff --git a/lib/ipc_setup.c b/lib/ipc_setup.c index 23eeabb21..f5dec9faa 100644 --- a/lib/ipc_setup.c +++ b/lib/ipc_setup.c @@ -494,6 +494,7 @@ qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c, qb_ipc_auth_creds(data); c->egid = data->ugp.gid; + c->euid = data->ugp.uid; c->server_pid = data->ugp.pid; destroy_ipc_auth_data(data); diff --git a/lib/ipcc.c b/lib/ipcc.c index e29209559..a6cf409b6 100644 --- a/lib/ipcc.c +++ b/lib/ipcc.c @@ -366,6 +366,24 @@ qb_ipcc_fd_get(struct qb_ipcc_connection * c, int32_t * fd) return 0; } +int32_t +qb_ipcc_auth_get(struct qb_ipcc_connection * c, pid_t *pid, uid_t *uid, gid_t *gid) +{ + if (c == NULL) { + return -EINVAL; + } + if (pid) { + *pid = c->server_pid; + } + if (uid) { + *uid = c->euid; + } + if (gid) { + *gid = c->egid; + } + return 0; +} + ssize_t qb_ipcc_event_recv(struct qb_ipcc_connection * c, void *msg_pt, size_t msg_len, int32_t ms_timeout) diff --git a/lib/unix.c b/lib/unix.c index 327ccdf8a..5f84cdfca 100644 --- a/lib/unix.c +++ b/lib/unix.c @@ -74,10 +74,12 @@ qb_sys_mmap_file_open(char *path, const char *file, size_t bytes, uint32_t file_flags) { int32_t fd; - int32_t i; int32_t res = 0; +#ifndef HAVE_POSIX_FALLOCATE ssize_t written; char *buffer = NULL; + int32_t i; +#endif char *is_absolute = strchr(file, '/'); if (is_absolute) { diff --git a/tests/check_ipc.c b/tests/check_ipc.c index 345c2afde..e8f81f3ac 100644 --- a/tests/check_ipc.c +++ b/tests/check_ipc.c @@ -1105,6 +1105,49 @@ test_ipc_txrx(void) } } +static void +test_ipc_getauth(void) +{ + int32_t j; + int32_t c = 0; + pid_t pid; + pid_t spid; + uid_t suid; + gid_t sgid; + int res; + uint32_t max_size = MAX_MSG_SIZE; + + pid = run_function_in_new_process("server", run_ipc_server, NULL); + ck_assert(pid != -1); + + do { + conn = qb_ipcc_connect(ipc_name, max_size); + if (conn == NULL) { + j = waitpid(pid, NULL, WNOHANG); + ck_assert_int_eq(j, 0); + poll(NULL, 0, 400); + c++; + } + } while (conn == NULL && c < 5); + ck_assert(conn != NULL); + + res = qb_ipcc_auth_get(NULL, NULL, NULL, NULL); + ck_assert(res == -EINVAL); + + res = qb_ipcc_auth_get(conn, &spid, &suid, &sgid); + ck_assert(res == 0); +#ifndef HAVE_GETPEEREID + /* GETPEEREID doesn't return a PID */ + ck_assert(spid != 0); +#endif + ck_assert(suid == getuid()); + ck_assert(sgid == getgid()); + + request_server_exit(); + qb_ipcc_disconnect(conn); + verify_graceful_stop(pid); +} + static void test_ipc_exit(void) { @@ -1193,6 +1236,27 @@ START_TEST(test_ipc_txrx_us_timeout) } END_TEST + +START_TEST(test_ipc_txrx_shm_getauth) +{ + qb_enter(); + ipc_type = QB_IPC_SHM; + set_ipc_name(__func__); + test_ipc_getauth(); + qb_leave(); +} +END_TEST + +START_TEST(test_ipc_txrx_us_getauth) +{ + qb_enter(); + ipc_type = QB_IPC_SOCKET; + set_ipc_name(__func__); + test_ipc_getauth(); + qb_leave(); +} +END_TEST + START_TEST(test_ipc_txrx_shm_tmo) { qb_enter(); @@ -2213,6 +2277,7 @@ make_shm_suite(void) TCase *tc; Suite *s = suite_create("shm"); + add_tcase(s, tc, test_ipc_txrx_shm_getauth, 7); add_tcase(s, tc, test_ipc_txrx_shm_timeout, 28); add_tcase(s, tc, test_ipc_server_fail_shm, 7); add_tcase(s, tc, test_ipc_txrx_shm_block, 7); @@ -2243,6 +2308,7 @@ make_soc_suite(void) Suite *s = suite_create("socket"); TCase *tc; + add_tcase(s, tc, test_ipc_txrx_us_getauth, 7); add_tcase(s, tc, test_ipc_txrx_us_timeout, 28); /* Commented out for the moment as space in /dev/shm on the CI machines causes random failures */