16cd6a6acSopenharmony_ci#include <unistd.h>
26cd6a6acSopenharmony_ci#include <fcntl.h>
36cd6a6acSopenharmony_ci#include <string.h>
46cd6a6acSopenharmony_ci#include <stdlib.h>
56cd6a6acSopenharmony_ci#include <errno.h>
66cd6a6acSopenharmony_ci#include <sys/socket.h>
76cd6a6acSopenharmony_ci#include "selinux_internal.h"
86cd6a6acSopenharmony_ci#include "policy.h"
96cd6a6acSopenharmony_ci
106cd6a6acSopenharmony_ci#ifndef SO_PEERSEC
116cd6a6acSopenharmony_ci#define SO_PEERSEC 31
126cd6a6acSopenharmony_ci#endif
136cd6a6acSopenharmony_ci
146cd6a6acSopenharmony_ciint getpeercon_raw(int fd, char ** context)
156cd6a6acSopenharmony_ci{
166cd6a6acSopenharmony_ci	char *buf;
176cd6a6acSopenharmony_ci	socklen_t size;
186cd6a6acSopenharmony_ci	ssize_t ret;
196cd6a6acSopenharmony_ci
206cd6a6acSopenharmony_ci	size = INITCONTEXTLEN + 1;
216cd6a6acSopenharmony_ci	buf = malloc(size);
226cd6a6acSopenharmony_ci	if (!buf)
236cd6a6acSopenharmony_ci		return -1;
246cd6a6acSopenharmony_ci	memset(buf, 0, size);
256cd6a6acSopenharmony_ci
266cd6a6acSopenharmony_ci	ret = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buf, &size);
276cd6a6acSopenharmony_ci	if (ret < 0 && errno == ERANGE) {
286cd6a6acSopenharmony_ci		char *newbuf;
296cd6a6acSopenharmony_ci
306cd6a6acSopenharmony_ci		newbuf = realloc(buf, size);
316cd6a6acSopenharmony_ci		if (!newbuf)
326cd6a6acSopenharmony_ci			goto out;
336cd6a6acSopenharmony_ci
346cd6a6acSopenharmony_ci		buf = newbuf;
356cd6a6acSopenharmony_ci		memset(buf, 0, size);
366cd6a6acSopenharmony_ci		ret = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buf, &size);
376cd6a6acSopenharmony_ci	}
386cd6a6acSopenharmony_ci      out:
396cd6a6acSopenharmony_ci	if (ret < 0)
406cd6a6acSopenharmony_ci		free(buf);
416cd6a6acSopenharmony_ci	else
426cd6a6acSopenharmony_ci		*context = buf;
436cd6a6acSopenharmony_ci	return ret;
446cd6a6acSopenharmony_ci}
456cd6a6acSopenharmony_ci
466cd6a6acSopenharmony_ci
476cd6a6acSopenharmony_ciint getpeercon(int fd, char ** context)
486cd6a6acSopenharmony_ci{
496cd6a6acSopenharmony_ci	int ret;
506cd6a6acSopenharmony_ci	char * rcontext;
516cd6a6acSopenharmony_ci
526cd6a6acSopenharmony_ci	ret = getpeercon_raw(fd, &rcontext);
536cd6a6acSopenharmony_ci
546cd6a6acSopenharmony_ci	if (!ret) {
556cd6a6acSopenharmony_ci		ret = selinux_raw_to_trans_context(rcontext, context);
566cd6a6acSopenharmony_ci		freecon(rcontext);
576cd6a6acSopenharmony_ci	}
586cd6a6acSopenharmony_ci
596cd6a6acSopenharmony_ci	return ret;
606cd6a6acSopenharmony_ci}
61