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 "selinux_internal.h"
9 #include "policy.h"
10 #include <limits.h>
11 
security_compute_user_raw(const char * scon,const char * user,char *** con)12 int security_compute_user_raw(const char * scon,
13 			      const char *user, char *** con)
14 {
15 	char path[PATH_MAX];
16 	char **ary;
17 	char *buf, *ptr;
18 	size_t size;
19 	int fd, ret;
20 	unsigned int i, nel;
21 
22 	if (!selinux_mnt) {
23 		errno = ENOENT;
24 		return -1;
25 	}
26 
27 	snprintf(path, sizeof path, "%s/user", selinux_mnt);
28 	fd = open(path, O_RDWR);
29 	if (fd < 0)
30 		return -1;
31 
32 	size = selinux_page_size;
33 	buf = malloc(size);
34 	if (!buf) {
35 		ret = -1;
36 		goto out;
37 	}
38 	snprintf(buf, size, "%s %s", scon, user);
39 
40 	ret = write(fd, buf, strlen(buf));
41 	if (ret < 0)
42 		goto out2;
43 
44 	memset(buf, 0, size);
45 	ret = read(fd, buf, size - 1);
46 	if (ret < 0)
47 		goto out2;
48 
49 	if (sscanf(buf, "%u", &nel) != 1) {
50 		ret = -1;
51 		goto out2;
52 	}
53 
54 	ary = malloc((nel + 1) * sizeof(char *));
55 	if (!ary) {
56 		ret = -1;
57 		goto out2;
58 	}
59 
60 	ptr = buf + strlen(buf) + 1;
61 	for (i = 0; i < nel; i++) {
62 		ary[i] = strdup(ptr);
63 		if (!ary[i]) {
64 			freeconary(ary);
65 			ret = -1;
66 			goto out2;
67 		}
68 		ptr += strlen(ptr) + 1;
69 	}
70 	ary[nel] = NULL;
71 	*con = ary;
72 	ret = 0;
73       out2:
74 	free(buf);
75       out:
76 	close(fd);
77 	return ret;
78 }
79 
hidden_def(security_compute_user_raw)80 hidden_def(security_compute_user_raw)
81 
82 int security_compute_user(const char * scon,
83 			  const char *user, char *** con)
84 {
85 	int ret;
86 	char * rscon;
87 
88 	if (selinux_trans_to_raw_context(scon, &rscon))
89 		return -1;
90 
91 	ret = security_compute_user_raw(rscon, user, con);
92 
93 	freecon(rscon);
94 	if (!ret) {
95 		char **ptr, *tmpcon;
96 		for (ptr = *con; *ptr; ptr++) {
97 			if (selinux_raw_to_trans_context(*ptr, &tmpcon)) {
98 				freeconary(*con);
99 				*con = NULL;
100 				return -1;
101 			}
102 			freecon(*ptr);
103 			*ptr = tmpcon;
104 		}
105 	}
106 
107 	return ret;
108 }
109 
110 hidden_def(security_compute_user)
111