]> git.ipfire.org Git - thirdparty/libbsd.git/commitdiff
Add getpeereid function
authorGuillem Jover <guillem@hadrons.org>
Fri, 17 Dec 2010 09:50:56 +0000 (10:50 +0100)
committerGuillem Jover <guillem@hadrons.org>
Sat, 14 May 2011 11:43:41 +0000 (13:43 +0200)
Makefile
Versions
include/bsd/unistd.h
src/getpeereid.3 [new file with mode: 0644]
src/getpeereid.c [new file with mode: 0644]

index fc4b9fd5d239b875d8d19b1f85bd69b187a4361b..4aa64ef5d574ae111de7d543ceea004042c44bf8 100644 (file)
--- 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 \
index f2df70cf6dc2ff7f9f0c5118f5d788afeaf7ed08..7c9437ec102df835437031fdd56313657a071231 100644 (file)
--- a/Versions
+++ b/Versions
@@ -67,5 +67,6 @@ LIBBSD_0.2 {
 
 LIBBSD_0.3 {
     reallocf;
+    getpeereid;
 } LIBBSD_0.2;
 
index f9f78748cea8a63ab54583bb91c918c507c2de02..2a22fbc20e77fa15338f73bee08198489561f589 100644 (file)
@@ -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 (file)
index 0000000..66ae6c2
--- /dev/null
@@ -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 (file)
index 0000000..8990357
--- /dev/null
@@ -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