summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--Versions1
-rw-r--r--include/bsd/unistd.h2
-rw-r--r--src/getpeereid.3138
-rw-r--r--src/getpeereid.c132
5 files changed, 275 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index fc4b9fd..4aa64ef 100644
--- a/Makefile
+++ b/Makefile
@@ -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 \
diff --git a/Versions b/Versions
index f2df70c..7c9437e 100644
--- a/Versions
+++ b/Versions
@@ -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