1#include <unistd.h>
2#include <sys/types.h>
3#include <fcntl.h>
4#include <stdlib.h>
5#include <stdio.h>
6#include <errno.h>
7#include <string.h>
8#include <limits.h>
9#include "selinux_internal.h"
10#include "policy.h"
11#include "mapping.h"
12
13int security_compute_relabel_raw(const char * scon,
14				 const char * tcon,
15				 security_class_t tclass,
16				 char ** newcon)
17{
18	char path[PATH_MAX];
19	char *buf;
20	size_t size;
21	int fd, ret;
22
23	if (!selinux_mnt) {
24		errno = ENOENT;
25		return -1;
26	}
27
28	snprintf(path, sizeof path, "%s/relabel", selinux_mnt);
29	fd = open(path, O_RDWR);
30	if (fd < 0)
31		return -1;
32
33	size = selinux_page_size;
34	buf = malloc(size);
35	if (!buf) {
36		ret = -1;
37		goto out;
38	}
39	snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass));
40
41	ret = write(fd, buf, strlen(buf));
42	if (ret < 0)
43		goto out2;
44
45	memset(buf, 0, size);
46	ret = read(fd, buf, size - 1);
47	if (ret < 0)
48		goto out2;
49
50	*newcon = strdup(buf);
51	if (!*newcon) {
52		ret = -1;
53		goto out2;
54	}
55	ret = 0;
56      out2:
57	free(buf);
58      out:
59	close(fd);
60	return ret;
61}
62
63hidden_def(security_compute_relabel_raw)
64
65int security_compute_relabel(const char * scon,
66			     const char * tcon,
67			     security_class_t tclass,
68			     char ** newcon)
69{
70	int ret;
71	char * rscon;
72	char * rtcon;
73	char * rnewcon;
74
75	if (selinux_trans_to_raw_context(scon, &rscon))
76		return -1;
77	if (selinux_trans_to_raw_context(tcon, &rtcon)) {
78		freecon(rscon);
79		return -1;
80	}
81
82	ret = security_compute_relabel_raw(rscon, rtcon, tclass, &rnewcon);
83
84	freecon(rscon);
85	freecon(rtcon);
86	if (!ret) {
87		ret = selinux_raw_to_trans_context(rnewcon, newcon);
88		freecon(rnewcon);
89	}
90
91	return ret;
92}
93