diff options
| author | Garrett D'Amore <garrett@damore.org> | 2018-05-03 14:28:44 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2018-05-03 15:14:45 -0700 |
| commit | afd555af4fba0acbf16c174dd9dece24181a1a38 (patch) | |
| tree | 9d49fec85c58ecad9a034a98e092627968494bc0 /src/platform/posix | |
| parent | fa986e725f08e30eab68e16765b2cf71613b871c (diff) | |
| download | nng-afd555af4fba0acbf16c174dd9dece24181a1a38.tar.gz nng-afd555af4fba0acbf16c174dd9dece24181a1a38.tar.bz2 nng-afd555af4fba0acbf16c174dd9dece24181a1a38.zip | |
fixes #383 Would like peerid for IPC
We offer uid, gid, process id, and even zone id where we have them.
Docs and tests are provided.
Diffstat (limited to 'src/platform/posix')
| -rw-r--r-- | src/platform/posix/posix_aio.h | 2 | ||||
| -rw-r--r-- | src/platform/posix/posix_ipc.c | 64 | ||||
| -rw-r--r-- | src/platform/posix/posix_pipedesc.c | 68 |
3 files changed, 134 insertions, 0 deletions
diff --git a/src/platform/posix/posix_aio.h b/src/platform/posix/posix_aio.h index 3954f225..7d6a7231 100644 --- a/src/platform/posix/posix_aio.h +++ b/src/platform/posix/posix_aio.h @@ -33,6 +33,8 @@ extern int nni_posix_pipedesc_peername(nni_posix_pipedesc *, nni_sockaddr *); extern int nni_posix_pipedesc_sockname(nni_posix_pipedesc *, nni_sockaddr *); extern int nni_posix_pipedesc_set_nodelay(nni_posix_pipedesc *, bool); extern int nni_posix_pipedesc_set_keepalive(nni_posix_pipedesc *, bool); +extern int nni_posix_pipedesc_get_peerid( + nni_posix_pipedesc *, uint64_t *, uint64_t *, uint64_t *, uint64_t *); extern int nni_posix_epdesc_init(nni_posix_epdesc **, int); extern void nni_posix_epdesc_set_local(nni_posix_epdesc *, void *, size_t); diff --git a/src/platform/posix/posix_ipc.c b/src/platform/posix/posix_ipc.c index c1bb9292..5ba3c8fb 100644 --- a/src/platform/posix/posix_ipc.c +++ b/src/platform/posix/posix_ipc.c @@ -183,4 +183,68 @@ nni_plat_ipc_pipe_recv(nni_plat_ipc_pipe *p, nni_aio *aio) nni_posix_pipedesc_recv((void *) p, aio); } +int +nni_plat_ipc_pipe_get_peer_uid(nni_plat_ipc_pipe *p, uint64_t *uid) +{ + int rv; + uint64_t ignore; + + if ((rv = nni_posix_pipedesc_get_peerid( + (void *) p, uid, &ignore, &ignore, &ignore)) != 0) { + return (rv); + } + return (0); +} + +int +nni_plat_ipc_pipe_get_peer_gid(nni_plat_ipc_pipe *p, uint64_t *gid) +{ + int rv; + uint64_t ignore; + + if ((rv = nni_posix_pipedesc_get_peerid( + (void *) p, &ignore, gid, &ignore, &ignore)) != 0) { + return (rv); + } + return (0); +} + +int +nni_plat_ipc_pipe_get_peer_zoneid(nni_plat_ipc_pipe *p, uint64_t *zid) +{ + int rv; + uint64_t ignore; + uint64_t id; + + if ((rv = nni_posix_pipedesc_get_peerid( + (void *) p, &ignore, &ignore, &ignore, &id)) != 0) { + return (rv); + } + if (id == (uint64_t) -1) { + // NB: -1 is not a legal zone id (illumos/Solaris) + return (NNG_ENOTSUP); + } + *zid = id; + return (0); +} + +int +nni_plat_ipc_pipe_get_peer_pid(nni_plat_ipc_pipe *p, uint64_t *pid) +{ + int rv; + uint64_t ignore; + uint64_t id; + + if ((rv = nni_posix_pipedesc_get_peerid( + (void *) p, &ignore, &ignore, &id, &ignore)) != 0) { + return (rv); + } + if (id == (uint64_t) -1) { + // NB: -1 is not a legal process id + return (NNG_ENOTSUP); + } + *pid = id; + return (0); +} + #endif // NNG_PLATFORM_POSIX diff --git a/src/platform/posix/posix_pipedesc.c b/src/platform/posix/posix_pipedesc.c index f9cbb94b..61005ca8 100644 --- a/src/platform/posix/posix_pipedesc.c +++ b/src/platform/posix/posix_pipedesc.c @@ -26,6 +26,12 @@ #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> +#if defined(NNG_HAVE_GETPEERUCRED) +#include <ucred.h> +#elif defined(NNG_HAVE_LOCALPEERCRED) +#include <sys/ucred.h> +#include <sys/un.h> +#endif // nni_posix_pipedesc is a descriptor kept one per transport pipe (i.e. open // file descriptor for TCP socket, etc.) This contains the list of pending @@ -402,6 +408,68 @@ nni_posix_pipedesc_init(nni_posix_pipedesc **pdp, int fd) return (0); } +int +nni_posix_pipedesc_get_peerid(nni_posix_pipedesc *pd, uint64_t *euid, + uint64_t *egid, uint64_t *prid, uint64_t *znid) +{ + int fd = pd->node.fd; +#if defined(NNG_HAVE_GETPEEREID) + uid_t uid; + gid_t gid; + + if (getpeereid(fd, &uid, &gid) != 0) { + return (nni_plat_errno(errno)); + } + *euid = uid; + *egid = gid; + *prid = (uint64_t) -1; + *znid = (uint64_t) -1; + return (0); +#elif defined(NNG_HAVE_GETPEERUCRED) + ucred *ucp; + if (getpeerucred(fd, &ucp) != 0) { + return (nni_plat_errno(errno)); + } + *euid = ucred_geteuid(ucp); + *egid = ucred_geteuid(ucp); + *prid = ucred_getpid(ucp); + *znid = ucred_getzoneid(ucp); + ucred_free(ucp); + return (0); +#elif defined(NNG_HAVE_SOPEERCRED) + struct ucred uc; + socklen_t len = sizeof(uc); + if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &uc, &len) != 0) { + return (nni_plat_errno(errno)); + } + *euid = uc.uid; + *egid = uc.gid; + *prid = uc.pid; + *znid = (uint64_t) -1; + return (0); +#elif defined(NNG_HAVE_LOCALPEERCRED) + struct xucred xu; + socklen_t len = sizeof(xu); + if (getsockopt(fd, SOL_LOCAL, LOCAL_PEERCRED, &xu, &len) != 0) { + return (nni_plat_errno(errno)); + } + *euid = xu.cr_uid; + *egid = xu.cr_gid; + *prid = (uint64_t) -1; // XXX: macOS has undocumented LOCAL_PEERPID... + *znid = (uint64_t) -1; + return (0); +#else + if (fd < 0) { + return (NNG_ECLOSED); + } + NNI_ARG_UNUSED(euid); + NNI_ARG_UNUSED(egid); + NNI_ARG_UNUSED(prid); + NNI_ARG_UNUSED(znid); + return (NNG_ENOTSUP); +#endif +} + void nni_posix_pipedesc_fini(nni_posix_pipedesc *pd) { |
