diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | Versions | 1 | ||||
-rw-r--r-- | include/bsd/unistd.h | 2 | ||||
-rw-r--r-- | src/getpeereid.3 | 138 | ||||
-rw-r--r-- | src/getpeereid.c | 132 |
5 files changed, 275 insertions, 0 deletions
@@ -26,6 +26,7 @@ LIB_SRCS := \ err.c \ fgetln.c \ flopen.c \ + getpeereid.c \ heapsort.c \ humanize_number.c \ dehumanize_number.c \ @@ -84,6 +85,7 @@ LIB_MANS := \ strlcat.3 \ fgetln.3 \ flopen.3 \ + getpeereid.3 \ readpassphrase.3 \ reallocf.3 \ humanize_number.3 \ @@ -67,5 +67,6 @@ LIBBSD_0.2 { LIBBSD_0.3 { reallocf; + getpeereid; } LIBBSD_0.2; diff --git a/include/bsd/unistd.h b/include/bsd/unistd.h index f9f7874..2a22fbc 100644 --- a/include/bsd/unistd.h +++ b/include/bsd/unistd.h @@ -39,6 +39,8 @@ mode_t getmode(const void *set, mode_t mode); void *setmode(const char *mode_str); void setproctitle(const char *fmt, ...); + +int getpeereid(int s, uid_t *euid, gid_t *egid); __END_DECLS #endif diff --git a/src/getpeereid.3 b/src/getpeereid.3 new file mode 100644 index 0000000..66ae6c2 --- /dev/null +++ b/src/getpeereid.3 @@ -0,0 +1,138 @@ +.\" +.\" Copyright (c) 2001 Dima Dorfman. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd July 15, 2001 +.Dt GETPEEREID 3 +.Os +.Sh NAME +.Nm getpeereid +.Nd get the effective credentials of a UNIX-domain peer +.Sh LIBRARY +.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd) +.Lb libbsd +.Sh SYNOPSIS +.In sys/types.h +.In unistd.h +.Ft int +.Fn getpeereid "int s" "uid_t *euid" "gid_t *egid" +.Sh DESCRIPTION +The +.Fn getpeereid +function returns the effective user and group IDs of the +peer connected to a +.Ux Ns -domain +socket. +The argument +.Fa s +must be a +.Ux Ns -domain +socket +.Pq Xr unix 4 +of type +.Dv SOCK_STREAM +on which either +.Xr connect 2 +or +.Xr listen 2 +have been called. +The effective used ID is placed in +.Fa euid , +and the effective group ID in +.Fa egid . +.Pp +The credentials returned to the +.Xr listen 2 +caller are those of its peer at the time it called +.Xr connect 2 ; +the credentials returned to the +.Xr connect 2 +caller are those of its peer at the time it called +.Xr listen 2 . +This mechanism is reliable; there is no way for either side to influence +the credentials returned to its peer except by calling the appropriate +system call (i.e., either +.Xr connect 2 +or +.Xr listen 2 ) +under different effective credentials. +.Pp +One common use of this routine is for a +.Ux Ns -domain +server +to verify the credentials of its client. +Likewise, the client can verify the credentials of the server. +.Sh IMPLEMENTATION NOTES +On +.Fx , +.Fn getpeereid +is implemented in terms of the +.Dv LOCAL_PEERCRED +.Xr unix 4 +socket option. +.Sh RETURN VALUES +.Rv -std getpeereid +.Sh ERRORS +The +.Fn getpeereid +function +fails if: +.Bl -tag -width Er +.It Bq Er EBADF +The argument +.Fa s +is not a valid descriptor. +.It Bq Er ENOTSOCK +The argument +.Fa s +is a file, not a socket. +.It Bq Er ENOTCONN +The argument +.Fa s +does not refer to a socket on which +.Xr connect 2 +or +.Xr listen 2 +have been called. +.It Bq Er EINVAL +The argument +.Fa s +does not refer to a socket of type +.Dv SOCK_STREAM , +or the kernel returned invalid data. +.El +.Sh SEE ALSO +.Xr connect 2 , +.Xr getpeername 2 , +.Xr getsockname 2 , +.Xr getsockopt 2 , +.Xr listen 2 , +.Xr unix 4 +.Sh HISTORY +The +.Fn getpeereid +function appeared in +.Fx 4.6 . diff --git a/src/getpeereid.c b/src/getpeereid.c new file mode 100644 index 0000000..8990357 --- /dev/null +++ b/src/getpeereid.c @@ -0,0 +1,132 @@ +/* + * Copyright © 2010 Guillem Jover + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> + +#include <errno.h> +#include <unistd.h> + +#if defined(SO_PEERCRED) +/* Linux and OpenBSD */ +int +getpeereid(int s, uid_t *euid, gid_t *egid) +{ +/* XXX: This should be autodetected at build time instead. */ +#if defined(__linux__) + struct ucred cred; +#elif defined(__OpenBSD__) + struct sockpeercred cred; +#endif + socklen_t credlen = sizeof(cred); + int ret; + + ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cred, &credlen); + if (ret != 0) + return ret; + + *euid = cred.uid; + *egid = cred.gid; + + return 0; +} +#elif defined(LOCAL_PEERCRED) +/* FreeBSD */ +#include <sys/ucred.h> + +int +getpeereid(int s, uid_t *euid, gid_t *egid) +{ + struct xucred cred; + socklen_t credlen = sizeof(cred); + int ret; + + ret = getsockopt(s, 0, LOCAL_PEERCRED, &cred, &credlen); + if (ret != 0) + return ret; + if (cred.cr_version != XUCRED_VERSION) + return EINVAL; + + *euid = cred.cr_uid; + *egid = cred.cr_gid; + + return 0; +} +#elif defined(LOCAL_PEEREID) +/* NetBSD */ +int +getpeereid(int s, uid_t *euid, gid_t *egid) +{ + struct unpcbid cred; + socklen_t credlen = sizeof(cred); + int ret; + + ret = getsockopt(s, 0, LOCAL_PEEREID, &cred, &credlen); + if (ret != 0) + return ret; + + *euid = cred.unp_euid; + *egid = cred.unp_egid; + + return 0; +} +#elif defined(__sun) +/* Solaris */ +int +getpeereid(int s, uid_t *euid, gid_t *egid) +{ + ucred_t cred_inst; + ucred_t *cred = &cred_inst; + int ret; + + ret = getpeerucred(s, &cred); + if (ret != 0) + return ret; + + *euid = ucred_geteuid(cred); + if (*euid < 0) + return -1; + *egid = ucred_getegid(cred); + if (*egid < 0) + return -1; + + return 0; +} +#else +#warning "This platform needs an implementation of getpeereid()" +int +getpeereid(int s, uid_t *euid, gid_t *egid) +{ + *euid = geteuid(); + *egid = getegid(); + + return 0; +} +#endif |