From 2a06309eddfc6b16a66b4c4d0a1850be197c825d Mon Sep 17 00:00:00 2001 From: Greg V Date: Fri, 3 Apr 2020 19:52:04 +0300 Subject: [PATCH] iochannel: support credentials passing on FreeBSD Part-of: --- src/pulsecore/creds.h | 2 +- src/pulsecore/iochannel.c | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/pulsecore/creds.h b/src/pulsecore/creds.h index 9fdbb4f7e..b599b569c 100644 --- a/src/pulsecore/creds.h +++ b/src/pulsecore/creds.h @@ -34,7 +34,7 @@ typedef struct pa_creds pa_creds; typedef struct pa_cmsg_ancil_data pa_cmsg_ancil_data; -#if defined(SCM_CREDENTIALS) +#if defined(SCM_CREDENTIALS) || defined(SCM_CREDS) #define HAVE_CREDS 1 diff --git a/src/pulsecore/iochannel.c b/src/pulsecore/iochannel.c index eb93176ec..38b79d173 100644 --- a/src/pulsecore/iochannel.c +++ b/src/pulsecore/iochannel.c @@ -261,6 +261,13 @@ ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) { #ifdef HAVE_CREDS +#ifdef __FreeBSD__ +typedef struct cmsgcred pa_ucred_t; +#define SCM_CREDENTIALS SCM_CREDS +#else +typedef struct ucred pa_ucred_t; +#endif + bool pa_iochannel_creds_supported(pa_iochannel *io) { struct { struct sockaddr sa; @@ -284,15 +291,19 @@ bool pa_iochannel_creds_supported(pa_iochannel *io) { } int pa_iochannel_creds_enable(pa_iochannel *io) { +#ifndef __FreeBSD__ int t = 1; +#endif pa_assert(io); pa_assert(io->ifd >= 0); +#ifndef __FreeBSD__ if (setsockopt(io->ifd, SOL_SOCKET, SO_PASSCRED, &t, sizeof(t)) < 0) { pa_log_error("setsockopt(SOL_SOCKET, SO_PASSCRED): %s", pa_cstrerror(errno)); return -1; } +#endif return 0; } @@ -303,9 +314,9 @@ ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l struct iovec iov; union { struct cmsghdr hdr; - uint8_t data[CMSG_SPACE(sizeof(struct ucred))]; + uint8_t data[CMSG_SPACE(sizeof(pa_ucred_t))]; } cmsg; - struct ucred *u; + pa_ucred_t *u; pa_assert(io); pa_assert(data); @@ -317,12 +328,15 @@ ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l iov.iov_len = l; pa_zero(cmsg); - cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(struct ucred)); + cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(pa_ucred_t)); cmsg.hdr.cmsg_level = SOL_SOCKET; cmsg.hdr.cmsg_type = SCM_CREDENTIALS; - u = (struct ucred*) CMSG_DATA(&cmsg.hdr); + u = (pa_ucred_t*) CMSG_DATA(&cmsg.hdr); +#ifdef __FreeBSD__ + // the kernel fills everything +#else u->pid = getpid(); if (ucred) { u->uid = ucred->uid; @@ -331,6 +345,7 @@ ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l u->uid = getuid(); u->gid = getgid(); } +#endif pa_zero(mh); mh.msg_iov = &iov; @@ -403,7 +418,7 @@ ssize_t pa_iochannel_read_with_ancil_data(pa_iochannel*io, void*data, size_t l, struct iovec iov; union { struct cmsghdr hdr; - uint8_t data[CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int) * MAX_ANCIL_DATA_FDS)]; + uint8_t data[CMSG_SPACE(sizeof(pa_ucred_t)) + CMSG_SPACE(sizeof(int) * MAX_ANCIL_DATA_FDS)]; } cmsg; pa_assert(io); @@ -439,12 +454,16 @@ ssize_t pa_iochannel_read_with_ancil_data(pa_iochannel*io, void*data, size_t l, continue; if (cmh->cmsg_type == SCM_CREDENTIALS) { - struct ucred u; - pa_assert(cmh->cmsg_len == CMSG_LEN(sizeof(struct ucred))); - memcpy(&u, CMSG_DATA(cmh), sizeof(struct ucred)); - + pa_ucred_t u; + pa_assert(cmh->cmsg_len == CMSG_LEN(sizeof(pa_ucred_t))); + memcpy(&u, CMSG_DATA(cmh), sizeof(pa_ucred_t)); +#ifdef __FreeBSD__ + ancil_data->creds.gid = u.cmcred_gid; + ancil_data->creds.uid = u.cmcred_uid; +#else ancil_data->creds.gid = u.gid; ancil_data->creds.uid = u.uid; +#endif ancil_data->creds_valid = true; } else if (cmh->cmsg_type == SCM_RIGHTS) {