diff options
Diffstat (limited to 'libselinux/src/getpeercon.c')
-rw-r--r-- | libselinux/src/getpeercon.c | 61 |
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; +} |