aboutsummaryrefslogtreecommitdiffstats
path: root/libselinux/src/getpeercon.c
diff options
context:
space:
mode:
Diffstat (limited to 'libselinux/src/getpeercon.c')
-rw-r--r--libselinux/src/getpeercon.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/libselinux/src/getpeercon.c b/libselinux/src/getpeercon.c
new file mode 100644
index 00000000..5c01ed50
--- /dev/null
+++ b/libselinux/src/getpeercon.c
@@ -0,0 +1,61 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include "selinux_internal.h"
+#include "policy.h"
+
+#ifndef SO_PEERSEC
+#define SO_PEERSEC 31
+#endif
+
+int getpeercon_raw(int fd, security_context_t * context)
+{
+ char *buf;
+ socklen_t size;
+ ssize_t ret;
+
+ size = INITCONTEXTLEN + 1;
+ buf = malloc(size);
+ if (!buf)
+ return -1;
+ memset(buf, 0, size);
+
+ ret = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buf, &size);
+ if (ret < 0 && errno == ERANGE) {
+ char *newbuf;
+
+ newbuf = realloc(buf, size);
+ if (!newbuf)
+ goto out;
+
+ buf = newbuf;
+ memset(buf, 0, size);
+ ret = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buf, &size);
+ }
+ out:
+ if (ret < 0)
+ free(buf);
+ else
+ *context = buf;
+ return ret;
+}
+
+hidden_def(getpeercon_raw)
+
+int getpeercon(int fd, security_context_t * context)
+{
+ int ret;
+ security_context_t rcontext;
+
+ ret = getpeercon_raw(fd, &rcontext);
+
+ if (!ret) {
+ ret = selinux_raw_to_trans_context(rcontext, context);
+ freecon(rcontext);
+ }
+
+ return ret;
+}