1f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <unistd.h>
2f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <fcntl.h>
3f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <string.h>
4f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <stdlib.h>
5f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <errno.h>
6f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <sys/xattr.h>
7f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include "selinux_internal.h"
8f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include "policy.h"
9f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
10f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyint lgetfilecon(const char *path, security_context_t * context)
11f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{
12f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	char *buf;
13f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	ssize_t size;
14f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	ssize_t ret;
15f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
16f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	size = INITCONTEXTLEN + 1;
17f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	buf = malloc(size);
18f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	if (!buf)
19f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		return -1;
20f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	memset(buf, 0, size);
21f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
22f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	ret = lgetxattr(path, XATTR_NAME_SELINUX, buf, size - 1);
23f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	if (ret < 0 && errno == ERANGE) {
24f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		char *newbuf;
25f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
26f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		size = lgetxattr(path, XATTR_NAME_SELINUX, NULL, 0);
27f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		if (size < 0)
28f074036424618c130dacb3464465a8b40bffef5Stephen Smalley			goto out;
29f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
30f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		size++;
31f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		newbuf = realloc(buf, size);
32f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		if (!newbuf)
33f074036424618c130dacb3464465a8b40bffef5Stephen Smalley			goto out;
34f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
35f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		buf = newbuf;
36f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		memset(buf, 0, size);
37f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		ret = lgetxattr(path, XATTR_NAME_SELINUX, buf, size - 1);
38f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	}
39f074036424618c130dacb3464465a8b40bffef5Stephen Smalley      out:
40f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	if (ret == 0) {
41f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		/* Re-map empty attribute values to errors. */
42f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		errno = EOPNOTSUPP;
43f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		ret = -1;
44f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	}
45f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	if (ret < 0)
46f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		free(buf);
47f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	else
48f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		*context = buf;
49f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	return ret;
50f074036424618c130dacb3464465a8b40bffef5Stephen Smalley}
51