summaryrefslogtreecommitdiff
path: root/common/unix-peer.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-08-24 11:37:36 +0200
committerDaiki Ueno <ueno@gnu.org>2017-02-17 10:25:55 +0100
commitf2742c72bc29444bcfe63425819506fa42073d64 (patch)
tree1d911238e539e654413e5614ef1c65410d0bc4e7 /common/unix-peer.c
parent89fa381ce5573a925b90da973cd8956937d79caa (diff)
common: New p11_get_upeer_id() function
Diffstat (limited to 'common/unix-peer.c')
-rw-r--r--common/unix-peer.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/common/unix-peer.c b/common/unix-peer.c
new file mode 100644
index 0000000..354ee02
--- /dev/null
+++ b/common/unix-peer.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2013 Nikos Mavrogiannopoulos
+ *
+ * This file is part of ocserv.
+ *
+ * ocserv is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ocserv is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+/* needed for struct ucred */
+#if defined(__linux__) && !defined(_GNU_SOURCE)
+#define _GNU_SOURCE
+#endif
+
+#include "unix-peer.h"
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/uio.h>
+#include <sys/errno.h>
+
+/* Returns the unix domain socket peer information.
+ * Returns zero on success.
+ */
+int
+p11_get_upeer_id (int cfd, uid_t *uid, uid_t *gid, pid_t *pid)
+{
+ int ret;
+#if defined(SO_PEERCRED)
+ struct ucred cr;
+ socklen_t cr_len;
+
+ cr_len = sizeof (cr);
+ ret = getsockopt (cfd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len);
+ if (ret == -1)
+ return -1;
+
+ if (uid)
+ *uid = cr.uid;
+
+ if (gid)
+ *gid = cr.gid;
+
+ if (pid)
+ *pid = cr.pid;
+
+#elif defined(HAVE_GETPEEREID)
+ /* *BSD/MacOSX */
+ uid_t euid;
+ gid_t egid;
+
+ ret = getpeereid (cfd, &euid, &egid);
+
+ if (ret == -1)
+ return -1;
+
+ if (uid)
+ *uid = euid;
+
+ if (gid)
+ *gid = egid;
+
+ if (pid)
+ *pid = -1;
+
+#else
+#error "Unsupported UNIX variant"
+#endif
+ return 0;
+}